﻿using SeriesManager.Enum;
using SeriesManager.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace SeriesManager.Configuration
{
    public class RoamingConfigurationData : IConfigurationData
    {
        private bool loading = false;

        public void Activate(SeriesModel[] seriesCollection)
        {
            foreach (var series in seriesCollection)
            {
                series.PropertyChanged -= series_PropertyChanged;
                series.PropertyChanged += series_PropertyChanged;

                series.Seasons.CollectionChanged -= Seasons_CollectionChanged;
                series.Seasons.CollectionChanged += Seasons_CollectionChanged;
                foreach (var season in series.Seasons)
                {
                    season.Episodes.CollectionChanged -= Episodes_CollectionChanged;
                    season.Episodes.CollectionChanged += Episodes_CollectionChanged;
                    foreach (var episode in season.Episodes)
                    {
                        episode.PropertyChanged -= episode_PropertyChanged;
                        episode.PropertyChanged += episode_PropertyChanged;
                    }
                }
            }
        }

        private void Episodes_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (EpisodeModel episode in e.NewItems)
                {
                    SetEpisodeState(episode);
                    episode.PropertyChanged += episode_PropertyChanged;
                }
            }
        }

        void Seasons_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (SeasonModel season in e.NewItems)
                {
                    foreach (var episode in season.Episodes)
                    {
                        SetEpisodeState(episode);
                    }
                    season.Episodes.CollectionChanged += Episodes_CollectionChanged;
                }                
            }
        }

        private void episode_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (this.loading)
            {
                return;
            }

            if (e.PropertyName == "State")
            {
                var episode = (EpisodeModel)sender;
                if (ApplicationData.Current.RoamingSettings.Containers.ContainsKey(episode.Season.Series.ID.ToString()))
                {
                    ApplicationData.Current.RoamingSettings.Containers[episode.Season.Series.ID.ToString()].Values[episode.ID.ToString()] = episode.State == WatchState.Watched;
                }                
            }
        }

        private void series_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (this.loading)
            {
                return;
            }

            if (e.PropertyName == "Subscription")
            {
                var series = (SeriesModel)sender;

                if (series.Subscription) 
                {
                    if (!ApplicationData.Current.RoamingSettings.Containers.ContainsKey(series.ID.ToString()))
                    {
                        ApplicationData.Current.RoamingSettings.CreateContainer(series.ID.ToString(), ApplicationDataCreateDisposition.Always);

                        foreach (var episode in series.Watched)
                        {
                            if (ApplicationData.Current.RoamingSettings.Containers.ContainsKey(series.ID.ToString()))
                            {
                                ApplicationData.Current.RoamingSettings.Containers[series.ID.ToString()].Values[episode.ID.ToString()] = episode.State == WatchState.Watched;
                            }
                        }
                    }
                }
                else 
                {
                    if (ApplicationData.Current.RoamingSettings.Containers.ContainsKey(series.ID.ToString()))
                    {
                        ApplicationData.Current.RoamingSettings.DeleteContainer(series.ID.ToString());
                    }
                }
            }
            else if (e.PropertyName == "FanArt")
            {
                var series = (SeriesModel)sender;

                if (series.FanArt != null && ApplicationData.Current.RoamingSettings.Containers.ContainsKey(series.ID.ToString()))
                {
                    ApplicationData.Current.RoamingSettings.Containers[series.ID.ToString()].Values["fanart"] = series.FanArt.ID;
                }
            }
        }

        public void Deactivate(SeriesModel[] seriesCollection)
        {
            foreach (var series in seriesCollection)
            {
                series.PropertyChanged -= series_PropertyChanged;

                foreach (var season in series.Seasons)
                {
                    foreach (var episode in season.Episodes)
                    {
                        episode.PropertyChanged -= episode_PropertyChanged;
                    }
                }
            }
        }

        public void Load(SeriesModel[] seriesCollection)
        {
            this.loading = true;

            foreach (var series in seriesCollection)
            {
                if (ApplicationData.Current.RoamingSettings.Containers.ContainsKey(series.ID.ToString()))
                {
                    series.Subscription = true;

                    if (ApplicationData.Current.RoamingSettings.Containers[series.ID.ToString()].Values.ContainsKey("fanart"))
                    {
                        series.FanArt = new Model.Banner.FanArtBannerModel(series.ID);
                        series.FanArt.ID = (int)ApplicationData.Current.RoamingSettings.Containers[series.ID.ToString()].Values["fanart"];
                    }

                    foreach (var season in series.Seasons)
                    {
                        foreach (var episode in season.Episodes)
                        {
                            SetEpisodeState(episode);
                        }
                    }
                }
            }

            this.loading = false;
        }

        private void SetEpisodeState(EpisodeModel episode)
        {
            if (ApplicationData.Current.RoamingSettings.Containers.ContainsKey(episode.Season.Series.ID.ToString()) && ApplicationData.Current.RoamingSettings.Containers[episode.Season.Series.ID.ToString()].Values.ContainsKey(episode.ID.ToString()))
            {
                episode.State = (bool)ApplicationData.Current.RoamingSettings.Containers[episode.Season.Series.ID.ToString()].Values[episode.ID.ToString()] ? WatchState.Watched : WatchState.Unwatched;
            }
        }
    }
}
